package ajaxjs;

import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE;
import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;
import static java.nio.file.StandardWatchEventKinds.OVERFLOW;

import java.io.*;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;

/**
 * 磁盘工具类
 * @author frank
 */
public class Fso {
	
	/**
	 * 读取文件（）
	 * http://www.cnblogs.com/lovebread/archive/2009/11/23/1609122.html
	 * 1、按字节读取文件内容2、按字符读取文件内容3、按行读取文件内容4、随机读取文件内容 
	 * @param fullFileName
	 * @return
	 * @throws FileNotFoundException
	 */
	public static String readFile(String fullFileName) throws FileNotFoundException {
		StringBuilder fileContent = new StringBuilder();

		File file = new File(fullFileName);
		if(!file.exists()){
			throw new FileNotFoundException(fullFileName + " 不存在！");
		}
			
		BufferedReader reader = null;
		@SuppressWarnings("unused")
		int line = 1;
		String tempString = null;

		try {
			// System.out.println("以行为单位读取文件内容，一次读一整行：");
			
			InputStreamReader read = new InputStreamReader(new FileInputStream(file),"UTF-8"); 
			reader = new BufferedReader(read);
			// 一次读入一行，直到读入null为文件结束
			while ((tempString = reader.readLine()) != null) {
				fileContent.append(tempString);
				fileContent.append("\n");
				// 显示行号
				// System.out.println("line " + line + ": " + tempString);
				line++;
			}
			reader.close();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (reader != null) {
				try {
					reader.close();
				} catch (IOException e1) {
				}
			}
		}
		
		return fileContent.toString();
	}

	/**
	 * 
	 * @param fullFileName
	 * @param fileContent
	 * @throws IOException
	 */
	public static void writeFile(String fullFileName, String fileContent) throws IOException{
		FileOutputStream fos = null;
		OutputStreamWriter writer = null;
		
		try {
			fos = new FileOutputStream(fullFileName);
			writer = new OutputStreamWriter(fos, "UTF-8");
			writer.write(fileContent);
		} catch (IOException e1) {
			System.out.println("写入文件" + fullFileName + "失败");
			throw e1;
//			e1.printStackTrace();
		} finally {
			try {
				if (writer != null)writer.close();
				if (fos != null)fos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	public static void writeFile(String fileName, byte[] b, int off, int len){
	    FileOutputStream fileOut = null;
		try {
			fileOut = new FileOutputStream(fileName);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}                    
	 
	    try {
	    	fileOut.write(b, off, len);
	    	fileOut.flush();
	    	if(fileOut != null)fileOut.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	// 文件监视
	
	/*
	 * <%@page import="com.ajaxjs.bigfoot.js.FileChangeMonitor,com.ajaxjs.bigfoot.js.FileChangeMonitor.*, java.io.*,java.nio.file.*,java.nio.file.StandardWatchEventKinds.*"%>
<%
FileChangeMonitor fm = new FileChangeMonitor();
FileChangeMonitor.monit("c:\\temp", new FileChangeListener() {  
	int i = 0;
    public void fileChanged(File file) {  
        try {  
        	i++;
            System.out.println("i:::" + i);
            System.out.println(file.getName());
        }catch (Throwable e) {  
            e.printStackTrace();  
        }  
    }  
});
%>
 * 监控文件变化。
　　这里推荐使用 JDK 7 NIO 中新增的 Watch Service API。Watch Service API 将尽可能使用操作系统的文件 API ，当操作系统不支持时，则使用轮询。简而言之，就是 JNI  + 轮询，自己实现轮询倒不难，但要实现跨平台的 JNI 调用就很啰嗦了。 
	 */
    public interface FileChangeListener {  
        public void fileChanged(File file);  
    } 
    
    
    public static void monit(final String dir, final FileChangeListener listener) {  
        new Thread() {  
            public void run() {  
                Path path = new File(dir).toPath();  
                WatchService watcher;  
                try {  
                    watcher = FileSystems.getDefault().newWatchService();  
                    path.register(watcher, ENTRY_CREATE, ENTRY_MODIFY);  
                } catch (IOException e) {  
                    e.printStackTrace();  
                    return;  
                }  
  
                while (true) {  
                    WatchKey key;  
                    try {  
                        key = watcher.take();  
                    } catch (InterruptedException _) {  
                        return;  
                    }  
  
                    processKey(path, key, listener);  
                }  
            };  
        }.start();  
    }  
  
    private static void processKey(Path path, WatchKey key, FileChangeListener listener) {  
        for (WatchEvent<?> event : key.pollEvents()) {  
            if (event.kind() == OVERFLOW)continue;  
  
            Path fileName = (Path) event.context();  
            File file = path.resolve(fileName).toFile();  
            listener.fileChanged(file);  
        }  
  
        key.reset();  
    }  
}
